package org.luosl.webmagicx.listeners

import java.text.DecimalFormat
import java.util.Date
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicLong

import org.luosl.webmagicx.SpiderCell
import org.luosl.webmagicx.utils.{DateUtils, Logging}
import us.codecraft.webmagic.scheduler.MonitorableScheduler
import us.codecraft.webmagic.{Request, Spider, SpiderListener}
import scala.collection.JavaConverters._


/**
  * 通用的爬虫监听
  * Created by luosl on 2017/12/6.
  */
class GeneralSpiderListener(spiderCell:SpiderCell) extends Logging with SpiderListener{

  val startTime:Date = new Date()

  private val _successCount:AtomicLong = new AtomicLong()

  private val _errorCount:AtomicLong = new AtomicLong()

  private val _errorRequests = new ConcurrentHashMap[Request,Unit]()

  override def onSuccess(request: Request): Unit = _successCount.getAndIncrement()

  override def onError(request: Request): Unit = {
    _errorCount.getAndIncrement()
    _errorRequests.put(request,Unit)
  }

  /**
    * 成功处理的页面数
    * @return
    */
  def successCount:Long = _successCount.get()

  /**
    * 失败的页面数
    * @return
    */
  def errorCount:Long = _errorCount.get()

  /**
    * 失败的请求
    * @return
    */
  def errorRequests:Seq[Request] = _errorRequests.keys().asScala.toSeq

  /**
    * 当前队列中Url个数
    * @return
    */
  def totalAndLeftRequestCount:(Int, Int) ={
    spiderCell.spider.getScheduler match {
      case ms:MonitorableScheduler =>
        (ms.getTotalRequestsCount(spiderCell.spider),ms.getLeftRequestsCount(spiderCell.spider))
      case _ => (-1, -1)
    }
  }

  /**
    * 获取运行时间
    * @return
    */
  def runTime: String = {
    val timeDiff:Double = (new Date().getTime - startTime.getTime).toDouble
    val hf:Int = 1000 * 60 * 60
    val mf:Int = 1000 * 60
    if(timeDiff / hf > 1){
      s"${numFormat(timeDiff / hf)} h"
    }else if(timeDiff / mf > 1){
      s"${numFormat(timeDiff / mf)} m"
    }else{
      s"${numFormat(timeDiff / 1000)} s"
    }
  }

  private def numFormat(d:Double): String ={
    val df:DecimalFormat = new DecimalFormat("#.00")
    df.format(d)
  }

}

